"""
time: 2024/10/31
title: StartServer
message:
新版本接口函数文件
"""
import os
import json
import datetime
import traceback
from flask_cors import CORS
from Tool.Record import Record
from Tool.Features import Features
from ApiFunctionGather.ApiFunction import ApiFunction
from flask import Flask, request, jsonify, render_template, redirect, make_response, url_for, send_from_directory, abort

# 用户页面根目录
user_page = "rpa_work"
# 静态文件页面目录
user_static = 'rpa_work/static'
# 后台管理目录
admin_page = "pwa"

# 定义接口服务信息
app = Flask(__name__)
# 设置跨域处理
CORS(app)

log = Record(name="接口服务", console=True)


# 连通性测试
@app.route('/', methods=["POST", "GET"])
def link():
    try:
        # 链接方式
        link_name = request.method
        user_ip = request.remote_addr
        now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        result = {
            "status": 0,
            "msg": f"接口链接成功，当前请求方式为【{link_name}】你的IP地址为【{user_ip}】",
            "server_time": now_time
        }
        log.info(f"【{user_ip}】发起了【{link_name}】请求")
        return jsonify(result)
    except BaseException as e:
        result = {"status": 1, "msg": e, "server_time": "YYYY-MM-DD HH:MM:SS"}
        return jsonify(result)


# 登录信息验证
@app.route('/login', methods=['POST'])
def login():
    result = {"status": 0, "sid": "", "msg": "OK", "user_name": "", "group": ""}
    try:
        # 获取数据参数
        user_ip = request.remote_addr or ''
        data = request.get_json()
        username = data.get('username', '')
        password = data.get('password', '')
        data = ApiFunction().login(user=username, pwd=password, ip=user_ip)
        if not data['status']:
            log.info(f"[{user_ip}]使用[{username}]发起了登录, 结果为[失败]")
            result['status'] = 1
            result['msg'] = data['msg']
        else:
            log.info(f"[{user_ip}]使用[{username}]发起了登录, 结果为[成功]")
            result['sid'] = data['sid']
            result['user_name'] = data['user_name']
            result['group'] = data['group']
    except BaseException as e:
        result['status'] = 2
        result['msg'] = "登录数据处理时服务器发生异常"
        log.error(f"发生了错误, 错误摘要[{str(e)}]\n详细信息:{traceback.format_exc()}")
    return jsonify(result)


# 工作状态接口
@app.route('/WorkingCondition', methods=['POST'])
def working_condition():
    try:
        # 获取参数
        data = request.get_json()
        robot_id = data.get('robot_id', '')
        status = data.get('status', '')
        sid = data.get('sid', '')
        ip = data.get('ip', '')
        page = data.get('page', 1)
        limit = data.get('limit', 100)
        function = ApiFunction().work_status(sid=sid, robot_id=robot_id, status=status, page=page, limit=limit, ip=ip)
        result = function
        if result['status']:
            result['status'] = 0
        else:
            result['status'] = 1
    except BaseException as e:
        result = {'status': 2, 'msg': "服务器处理数据时发生异常发生异常"}
        log.error(f"发生了错误, 错误摘要[{str(e)}]\n详细信息:{traceback.format_exc()}")
    return jsonify(result)


# 机器人信息修改
@app.route('/robot/info/set', methods=['POST'])
def robot_info_update():
    result = {'status': True, 'msg': 'OK'}
    try:
        # 获取数据
        data = request.get_json()
        sid = data.get('sid', '')
        rid = data.get('robot_id', '')
        name = data.get('name', '')
        status = data.get('status', '')
        health = data.get('health', '')
        user_name = data.get('username', '')
        value = ApiFunction().robot_info_set(sid=sid, robot=rid, ip=data.get('ip', ''), name=name, status=status,
                                             health=health, username=user_name, remark=data.get('remark', ''))
        if value['status']:
            result = value
            result['status'] = 0
            log.info(f"修改设备信息完成, 执行信息[{json.dumps(data)}]")
        else:
            result = value
            result['status'] = 1
    except BaseException as e:
        log.error(f"接口’/robot/info/set‘发生异常, 异常信息[{e}], {traceback.format_exc()}")
        result['status'] = 2
        result['msg'] = "服务器发生异常"
    return jsonify(result)


# 机器人信息新增
@app.route('/robot/info/new', methods=['POST'])
def robot_info_new():
    result = {'status': True, 'msg': 'OK'}
    try:
        # 获取数据
        val_data = request.get_json()
        sid = val_data.get('sid', '')
        ip = val_data.get('ip', '')
        name = val_data.get('name', '')
        status = val_data.get('status', '')
        health = val_data.get('health', '')
        user_name = val_data.get('username', '')
        remark = val_data.get('remark', '')
        value = ApiFunction().robot_info_new(sid=sid, ip=ip, name=name, status=status, health=health,
                                             username=user_name, remark=remark)
        if value['status']:
            result = value
            result['status'] = 0
            log.info(f"新增设备信息完成, 执行信息[{json.dumps(val_data)}]")
        else:
            result = value
            result['status'] = 1
    except BaseException as e:
        log.error(f"接口’/robot/info/new‘发生异常, 异常信息[{e}],{traceback.format_exc()}")
        result['status'] = 2
        result['msg'] = "服务器发生异常"
    return jsonify(result)


# 机器人信息删除
@app.route('/robot/info/del', methods=['POST'])
def robot_info_del():
    result = {'status': True, 'msg': 'OK'}
    try:
        # 获取数据
        data = request.get_json()
        sid = data.get('sid', '')
        rid = data.get('robot_id', '')
        value = ApiFunction().robot_info_del(sid=sid, robot_id=rid)
        if value['status']:
            result = value
            result['status'] = 0
            log.info(f"删除设备信息完毕, 执行信息[{json.dumps(data)}]")
        else:
            result = value
            result['status'] = 1
    except BaseException as e:
        log.error(f"接口’/robot/info/del‘发生异常, 异常信息[{e}]{traceback.format_exc()}")
        result['status'] = 2
        result['msg'] = "服务器发生异常"
    return jsonify(result)


# 任务列表
@app.route('/Quest_list', methods=['POST'])
def quest_list():
    result = {'status': 1, 'msg': 'OK;', 'count': 0, 'data': []}
    try:
        # 获取参数
        data = request.get_json()
        sid = data.get('sid', '')
        robot_id = data.get('robot_id', '')
        flow_id = data.get('flow_id', '')
        flow_name = data.get('flow_name', '')
        value = ApiFunction().quest_list(sid=sid, robot_id=robot_id, flow_id=flow_id, flow_name=flow_name,
                                         page=data.get('page', 1), limit=data.get('limit', 100))
        result = value
        if value:
            result['status'] = 0
        else:
            result['status'] = 1
    except BaseException as e:
        log.error(f"接口’/Quest_list‘发生异常, 异常信息[{e}]{traceback.format_exc()}")
        result['status'] = 2
        result['msg'] = "服务器发生异常"
    return jsonify(result)


# 执行历史
@app.route('/Execution_history', methods=['POST'])
def execution_history():
    result = {'status': 1, 'msg': 'OK;', 'count': 0, 'data': []}
    try:
        # sid, flow_id, robot_id, user_id, status, start_time, stop_time, progress, group
        data = request.get_json()
        sid = data.get('sid', '')
        flow_id = data.get('flow_id', '')
        robot_id = data.get('robot_id', '')
        user_id = data.get('user_id', '')
        status = data.get('status', '')
        start_time = data.get('start_time', '')
        stop_time = data.get('stop_time', '')
        progress = data.get('progress', '')
        group = data.get('group', '')
        flow_name = data.get('flow_name', '')
        value = ApiFunction().execution_history(sid=sid, flow_id=flow_id, robot_id=robot_id, user_id=user_id,
                                                status=status, start_time=start_time, stop_time=stop_time,
                                                progress=progress, group=group, flow_name=flow_name,
                                                page=data.get('page', 1),
                                                limit=data.get('limit', 100))
        result = value
        if value:
            result['status'] = 0
        else:
            result['status'] = 1
    except BaseException as e:
        log.error(f"接口’/Execution_history‘发生异常, 异常信息[{e}]{traceback.format_exc()}")
        result['status'] = 2
        result['msg'] = "服务器发生异常"
    return jsonify(result)


@app.route('/flow/info/add', methods=['POST'])
def flow_info_add():
    result = {'status': 1, 'msg': 'OK;', 'sid': ''}
    try:
        data = request.get_json()
        value = ApiFunction().flow_info_add(sid=data.get('sid', None), robot_id=data.get('robot_id', None),
                                            mrpa_id=data.get('mrpa_id', None), flow_name=data.get('flow_name', None),
                                            file_path=data.get('file_path', None), file_md5=data.get('file_md5', None),
                                            grouping=data.get('grouping', None), status=data.get('status', None))
        result = value
        if value['status']:
            result['status'] = 0
            log.info(f"新增流程信息成功, 执行信息[{json.dumps(data)}]")
        else:
            result['status'] = 1
            log.error(f"新增流程信息失败, 执行信息[{json.dumps(data)}]")
    except BaseException as e:
        log.error(f"接口’/flow/info/add‘发生异常, 异常信息[{e}]{traceback.format_exc()}")
        result['status'] = 2
        result['msg'] = "服务器发生异常"
    return jsonify(result)


# 开始执行流程
@app.route('/start_flow', methods=['POST'])
def start_flow():
    # 需要直接调用机器人接口
    result = {'status': 1, 'msg': 'OK;', 'sid': ''}
    try:
        data = request.get_json()
        sid = data.get('sid', '')
        flow_id = data.get('flow_id', '')
        flow_name = data.get('flow_name', '')
        robot_id = data.get('robot_id', '')
        user_id = data.get('user_id', '')
        value = ApiFunction().start_flow(sid=sid, flow_id=flow_id, flow_name=flow_name, robot_id=robot_id,
                                         user_id=user_id)
        result = value
        if value['status']:
            result['status'] = 0
            log.info(f"执行流程[{flow_name}]成功, 执行信息:[{json.dumps(data)}]")
        else:
            result['status'] = 1
            log.info(f"执行流程[{flow_name}]失败, 执行信息:[{json.dumps(data)}]")
    except BaseException as e:
        log.error(f"接口’/start_flow‘发生异常, 异常信息[{e}]{traceback.format_exc()}")
        result['status'] = 2
        result['msg'] = "服务器发生异常"
    return jsonify(result)


# 结束执行流程
@app.route('/stop_flow', methods=['POST'])
def stop_flow():
    # 需要直接机器人接口
    result = {'status': 1, 'msg': 'OK;', 'sid': ''}
    try:
        data = request.get_json()
        sid = data.get('sid', '')
        robot_id = data.get('robot_id', '')
        flow_id = data.get('flow_id', '')
        value = ApiFunction().stop_flow(sid=sid, robot_id=robot_id, flow_id=flow_id)
        result = value
        if value['status']:
            result['status'] = 0
            log.info(f"结束执行流程[{flow_id}]成功, 结束信息:[{json.dumps(data)}]")
        else:
            result['status'] = 1
            log.info(f"结束执行流程[{flow_id}]失败, 结束信息:[{json.dumps(data)}]")
    except BaseException as e:
        log.error(f"接口’/stop_flow‘发生异常, 异常信息[{e}]{traceback.format_exc()}")
        result['status'] = 2
        result['msg'] = "服务器发生异常"
    return jsonify(result)


# 流程运行记录/进度  -- RPA 流程更新使用  不给前端更新使用了
@app.route('/FlowRunningRecord', methods=['POST'])
def flow_running_record():
    result = {'status': 1, 'msg': 'OK;', 'sid': '', 'data': []}
    try:
        data = request.get_json()
        sid = data.get('sid', '')
        flow_id = data.get('flow_id', '')
        flow_name = data.get('flow_name', '')
        progress = data.get('progress', '')
        robot_id = data.get('robot_id', '')
        flow_id_list = data.get('flow_id_list', [])
        value = ApiFunction().flow_running_record(sid=sid, flow_id=flow_id, progress=progress,
                                                  flow_id_list=flow_id_list, flow_name=flow_name, robot_id=robot_id)
        result = value
        if value:
            result['status'] = 0
            log.info(f"更新流程运行记录成功, 更新信息:[{json.dumps(data)}]")
        else:
            result['status'] = 1
            log.info(f"更新流程运行记录失败, 更新信息:[{json.dumps(data)}]")
    except BaseException as e:
        log.error(f"接口’/FlowRunningRecord‘发生异常, 异常信息[{e}]{traceback.format_exc()}")
        result['status'] = 2
        result['msg'] = "服务器发生异常"
    return jsonify(result)


# 添加/更新 上传文件
@app.route('/FileUpload', methods=['POST'])
def file_upload():
    try:
        result = {'status': 1, 'msg': '未获取到上传的文件', 'save_path': ''}
        file = None
        file_name = None
        if 'file' in request.files:
            file = request.files['file']
        else:
            result['nsg'] = "未检测到上传的文件"
        if request.files['file'].filename != '':
            file_name = request.files['file'].filename
        else:
            result['msg'] = "未获取到文件名"

        if file is not None and file_name is not None:
            result['status'] = 0
            # 获取参数
            sid = request.form.get('sid', '')
            file_id = request.form.get('file_id', '')
            flow_id = request.form.get('flow_id', '')
            result = ApiFunction().file_upload(sid=sid, ids=file_id, file_name=file_name, flow_id=flow_id)
            if result['status']:
                result['status'] = 0
                save_path = result['server_path']
                print(save_path)
                file.save(save_path)
                log.info(f"文件上传成功, 文件名:[{file_name}], 保存路径:[{save_path}]")
    except BaseException as e:
        log.error(f"接口/FileUpload发生异常, 异常信息[{e}]{traceback.format_exc()}")
        result = {'status': 2, 'msg': f"文件上传发生异常", 'sid': '', 'path': ''}
    return jsonify(result)


# 获取文件上传历史信息
@app.route('/file/history', methods=['POST'])
def file_history():
    result = {'status': 1, 'msg': 'OK;', 'sid': '', 'data': [], 'count': 0}
    try:
        data = request.get_json()
        sid = data.get('sid', '')
        file_id = data.get('file_id', '')
        file_name = data.get('file_name', '')
        flow_id = data.get('flow_id', '')
        flow_name = data.get('flow_name', '')
        date = data.get('date', '')
        values = ApiFunction().file_history(sid=sid, file_id=file_id, file_name=file_name, flow_id=flow_id, date=date,
                                            page=data.get('page', 1), limit=data.get('limit', 100), flow_name=flow_name)
        result = values
        if values['status']:
            result['status'] = 0
            log.info(f"获取文件历史信息成功")
        else:
            result['status'] = 1
            log.info(f"获取文件历史信息失败")
    except BaseException as e:
        log.error(f"接口’/file/history‘发生异常, 异常信息[{e}]{traceback.format_exc()}")
        result['status'] = 2
        result['msg'] = "服务器发生异常"
    return jsonify(result)


@app.route('/file/del', methods=['POST'])
def file_del():
    result = {'status': 1, 'msg': 'OK;', 'sid': ''}
    try:
        data = request.get_json()
        sid = data.get('sid', '')
        values = ApiFunction().del_file(sid=sid, file_id=data.get('file_id', ''),
                                        file_id_list=data.get('file_id_list', []),
                                        file_name=data.get('file_name', ''))
        result = values
        if values['status']:
            result['status'] = 0
            log.info(f"删除文件成功, 获取信息:[{json.dumps(data)}]")
        else:
            result['status'] = 1
            log.info(f"删除文件失败")
    except BaseException as e:
        log.error(f"接口’/file/del‘发生异常, 异常信息[{e}]{traceback.format_exc()}")
        result['status'] = 2
        result['msg'] = "服务器发生异常"
    return jsonify(result)


def handle_api_call(api_function, success_msg, failure_msg, *args, **kwargs):
    result = {'status': 1, 'msg': 'OK;', 'sid': ''}
    try:
        values = api_function(*args, **kwargs)
        result = values
        if values['status']:
            result['status'] = 0
            log.info(success_msg)
        else:
            result['status'] = 1
            log.info(failure_msg)
    except BaseException as e:
        log.error(f"接口发生异常, 异常信息[{e}]{traceback.format_exc()}")
        result['status'] = 2
        result['msg'] = "服务器发生异常"
    return jsonify(result)


@app.route('/user/all', methods=['POST'])
def user_all():
    return handle_api_call(
        ApiFunction().user_all,
        f"获取用户列表成功",
        f"获取用户列表失败",
        sid=request.get_json().get('sid', ''),
        user_id=request.get_json().get('user_id', ''),
        page=request.get_json().get('page', 1),
        limit=request.get_json().get('limit', 100)
    )


@app.route('/user/new', methods=['POST'])
def user_new():
    data = request.get_json()
    sid = data.get('sid', '')
    user = data.get('user', '')
    name = data.get('name', '')
    password = data.get('password', '')
    grouping = data.get('group', '')
    return handle_api_call(
        ApiFunction().user_new,
        f"新增用户信息成功, 执行信息:[{json.dumps(data)}]",
        f"新增用户信息失败, 执行信息:[{json.dumps(data)}]",
        sid=sid, user=user, pwd=password, name=name, grouping=grouping
    )


@app.route('/user/set', methods=['POST'])
def user_set():
    data = request.get_json()
    sid = data.get('sid', '')
    user_id = data.get('user_id', '')
    user = data.get('user', '')
    pwd = data.get('password', '')
    name = data.get('name', '')
    grouping = data.get('grouping', '')
    return handle_api_call(
        ApiFunction().user_set,
        f"修改用户信息成功, 执行信息:[{json.dumps(data)}]",
        f"修改用户信息失败, 执行信息:[{json.dumps(data)}]",
        sid=sid, user_id=user_id, user=user, pwd=pwd, name=name, grouping=grouping
    )


@app.route('/user/del', methods=['POST'])
def user_del():
    data = request.get_json()
    sid = data.get('sid', '')
    password = data.get('password', '')
    user = data.get('user', '')
    return handle_api_call(
        ApiFunction().user_del,
        f"删除用户信息成功, 执行信息:[{json.dumps(data)}]",
        f"删除用户信息失败, 执行信息:[{json.dumps(data)}]",
        password=password, user=user, sid=sid
    )


# 页面管理接口
@app.route('/pwa')
def background():
    """
    返回后台管理页面
    :return:
    """
    ip = Features().get_ip()
    # ip = '127.0.0.1'
    # 设置管理员页面地址
    app.template_folder = admin_page
    app.static_folder = 'pwa/static'
    return render_template('login.html', server_ip=ip, version="1.2.1")


@app.route('/background/workbench')
def background_background():
    """
    返回后台管理页面
    :return:
    """
    # 获取参数，重定向，设置cookie对象
    # sid = request.cookies.get('sid', '')
    # if sid == '':
    log.info("重定向")
    resp = make_response(redirect(url_for('workbench')))
    sid = request.args.get('sid', '')
    username = request.args.get('username', '')
    # 设置 cookie
    resp.set_cookie('sid', sid)
    resp.set_cookie('username', username)
    if not ApiFunction().sid_check(sid):
        return redirect(url_for('background'))
    return resp


@app.route('/workbench')
def workbench():
    log.info("返回页面")
    # 获取cookie，解析参数返回 页面
    ip = Features().get_ip()
    # ip = '127.0.0.1'
    title = "工作台小助手-管理页面"
    user_name = request.cookies.get('username', '')
    sid = request.cookies.get('sid', '')
    if not ApiFunction().sid_check(sid):
        return redirect(url_for('pwa'))
    log.info(f"后台管理页面 获取到信息[{title}][{user_name}][{request.cookies}]")
    # 设置管理员页面地址
    app.template_folder = admin_page
    app.static_folder = 'pwa/static'
    return render_template('workbench.html', server_ip=ip, title=title, user_name=user_name)


# 用访问界面地址
@app.route('/RpaWork')
def rpa_work_page():
    # 获取cookie，解析参数返回 页面
    ip = Features().get_ip()
    app.template_folder = user_page
    app.static_folder = user_static
    return render_template('index.html', server_ip=ip, )


# 如果访问RPA地址则会重定向至RpaWork
@app.route('/rpa')
def rpa_work_redirect():
    return redirect(url_for('rpa_work_page'))


@app.route('/RPA')
def rpa_work_redirect_t():
    return redirect(url_for('rpa_work_page'))


# 用户页面其他文件访问
@app.route('/rpa_work/<path:filepath>')
def get_c_file(filepath):
    # 构建文件路径
    base_dir = './rpa_work'
    full_path = os.path.join(base_dir, filepath)
    # 确保路径不会跳出 base_dir（可选，但推荐）
    if not os.path.abspath(full_path).startswith(os.path.abspath(base_dir)):
        print(f"访问文件[{full_path}][{filepath}]发生异常")
        abort(403)  # 禁止访问上级目录

    # 检查文件是否存在且是一个文件（而不是目录）
    if os.path.isfile(full_path):
        folder = os.path.normpath(full_path)
        log.info(f"访问文件：{folder}")
        return send_from_directory(os.path.dirname(folder), os.path.basename(full_path))
        # 返回文件
    else:
        log.error(f"文件不存在，路径为：{full_path}")
        abort(404)


@app.route('/rpa/sql/run', methods=['POST'])
def rpa_sql_run():
    """
    执行SQL
    :return:
    """
    result = {'status': 1, 'data': [], 'msg': "OK"}
    try:
        data = request.get_json()
        print(data)
        result = ApiFunction().api_sql_runner(sid=data.get('sid', ''),
                                              sql_lang=data.get('sql_lang', None),
                                              font_list=data.get('font_list', None))
        if result['status']:
            result['status'] = 0
        else:
            result['status'] = 1
    except BaseException as e:
        result['status'] = 2
        result['msg'] = str(e)
    return result


if __name__ == '__main__':
    print(f"""
                ==            ===============
                ||           ||
                ||           ||
                ||           ||
                ||           ||
                =============================
                             ||            ||
                             ||            ||
                             ||            ||
                             ||            ||
                ===============            ==

              --||======> 希特勒永不毁灭 <=====||--

    --||======>限制IP：{'0.0.0.0'}  0表示所有
    --||======>访问端口：{10801}
    """)
    app.run(host='0.0.0.0', port=10801)
